package org.bhf.providers.security;

import org.bhf.service.CSRTokenFacility;

import java.security.SecureRandom;
import java.util.Random;

/**
 * Password based encryption of CSR tokens. The password is randomly generated when the Facility is instantiated. Thus
 * tokens become invalid when the application is restarted. This technique will not work across clustered servers.
 */
public class PBECSRTokenFacility implements CSRTokenFacility
{
    /** The password must be shared across all in the same JVM */
    private static final String password;

    private long toleranceMillis = 24L * 60L * 60L * 1000L;

    static
    {
        final Random r = new SecureRandom();
        final byte[] b = new byte[16];

        r.nextBytes( b );
        password = Crypto.base64Encode( b );
    }

    void setToleranceMillis( final long toleranceMillis )
    {
        this.toleranceMillis = toleranceMillis;
    }

    //
    // Contract
    //

    /**
     * @inheritDoc
     */
    public String   getToken( final String serviceGroupName, final String serviceName )
    {
        return new CSRFToken( serviceGroupName, serviceName).encrypt( password.toCharArray() );
    }

    /**
     * @inheritDoc
     */
    public boolean  validateToken( final String encrypted, final String serviceGroupName, final String serviceName )
    {
        return encrypted != null && new CSRFToken( encrypted, password.toCharArray() ).verify( serviceGroupName, serviceName, toleranceMillis );
    }
}